﻿// Uninstall.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <Windows.h>
#include <vector>
#include <fstream>
#include <TlHelp32.h>

#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )

static const std::string UNINSTALL_KEY = "Software\\Microsoft\\Jinzhangshu\\IntoTheVoid";
static const std::string UNINSTALL_VERSION_KEY = "Software\\Microsoft\\Jinzhangshu\\IntoTheVoid\\Version";

std::string GetRegValue(const std::string& key)
{
	HKEY hkey = nullptr;
	LSTATUS res = ::RegOpenKeyExA(HKEY_CURRENT_USER, UNINSTALL_KEY.c_str(), 0, KEY_READ, &hkey);
	if (res != ERROR_SUCCESS)
		return "";

	std::shared_ptr<void> close_key(nullptr, [&](void*) {
		if (hkey != nullptr) {
			::RegCloseKey(hkey);
			hkey = nullptr;
		}
		});
	DWORD type = REG_SZ;
	DWORD size = 0;
	res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, nullptr, &size);
	if (res != ERROR_SUCCESS || size <= 0)
		return "";

	std::vector<BYTE> value_data(size);
	res = ::RegQueryValueExA(hkey, key.c_str(), 0, &type, value_data.data(), &size);
	if (res != ERROR_SUCCESS)
		return "";

	return std::string(value_data.begin(), value_data.end());
}

static bool IsFileExists(const std::string& name) {
	std::ifstream f(name.c_str());
	return f.good();
}

BOOL TerminateProcessByName(const std::wstring& strProcName)
{
	BOOL bExist = TRUE;
	PROCESSENTRY32W pe32 = { sizeof(PROCESSENTRY32W) };
	HANDLE hProcess = NULL;
	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	std::vector<DWORD> vecPID;

	if (hProcessSnap == INVALID_HANDLE_VALUE)
		return FALSE;

	if (!Process32FirstW(hProcessSnap, &pe32))
		return FALSE;

	do
	{
		if (_wcsnicmp(pe32.szExeFile, strProcName.c_str(), strProcName.size()) == 0)
			vecPID.push_back(pe32.th32ProcessID);
	} while (Process32NextW(hProcessSnap, &pe32));

	if (hProcessSnap)
	{
		CloseHandle(hProcessSnap);
		hProcessSnap = NULL;
	}

	for (size_t i = 0; i < vecPID.size(); i++)
	{
		HANDLE hProcess = OpenProcess(
			PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,
			FALSE,
			vecPID[i]);

		if (hProcess)
			TerminateProcess(hProcess, 0);

		if (hProcess)
		{
			CloseHandle(hProcess);
			hProcess = NULL;
		}
	}
	return TRUE;
}


int main()
{
	//// 删除version键值
	//int ret = RegDeleteKey(HKEY_CURRENT_USER, UNINSTALL_VERSION_KEY.c_str());

	BOOL terminateResult = TerminateProcessByName(L"IntoTheVoid");

	std::string uninstallPath = const_cast<char*>(GetRegValue("UninstallPackage").c_str());
	if (uninstallPath == "")
		return 0;

	uninstallPath += "\\IntoTheVoidSetup.exe";

	if (!IsFileExists(uninstallPath))
		return 0;


	ShellExecuteA(NULL, "runas", uninstallPath.c_str(), "/uninstall", NULL, SW_SHOW);
	return 0;
}
